This invention relates to the field of application development and analysis, and in particular to a method and system that analyzes an application's use of memory, to identify memory leaks and their causes.
The increasing level of complexity and sophistication of application programs has resulted in a significant increase in the amount of memory being used in such applications. Even though the cost of memory has significantly decreased over time, allowing for systems with substantial amounts of memory, the amount of memory available still remains a finite quantity.
If an application consumes an inordinate amount of memory, it will generally result in poor performance, and may result in failure of the application, and in some cases, a system failure. If the application is used for commercial transactions, such as operating a vendor's website, such poor performance and/or unreliable performance can result in the loss of sales, and in many cases, the loss of repeat customers. If the application is used for managing a business, such as an accounting or inventory application, poor or unreliable performance will result in a loss of productivity, and other problems.
A primary cause of excessive memory utilization is the presence of “memory leaks” within an application. As an application is run, it will typically request allocations of memory as required for each task, then release the memory for subsequent allocation to other tasks as each task is completed. The release of memory may be direct or indirect. In systems that use direct release, the designer explicitly de-allocates the memory when it is no longer required. If the user does not explicitly de-allocate memory that is no longer required, that memory is not made available for subsequent allocations.
In systems that use indirect release, the user releases memory by decoupling the links/references to the items that are no longer being used, and the system periodically performs ‘garbage collection’ to perform the de-allocation that identifies the memory as being available for subsequent reallocation. For example, terminating a subroutine that had allocated memory for ‘local’ variables that are only used within the subroutine will decouple the links to this memory, because these local variables are no longer within the current scope of the program. The next time the garbage collector is run, it will determine all of the ‘reachable’ objects (objects within the current scope of the program), and will de-allocate/release/free any memory that is not allocated to a reachable object. Although garbage collectors alleviate the task of explicitly releasing memory when it is no longer required, they are not fool-proof, particularly if the creator of the application is careless with regard to controlling the scope of variables.
If the release of memory is not properly performed, the amount of memory available for subsequent allocation will decrease; this loss of allocatable/available/free memory is termed a memory leak. If a memory leak continues over time, the amount of allocatable memory will decrease to a point that a substantial amount of time will be consumed by the system as it tries to satisfy each subsequent allocation request with less and less available memory; eventually, the amount of allocatable memory will decrease to a point at which the application cannot continue, for lack of available memory, even though the memory that was not properly released is not being used.
In prior decades, most systems and applications were used sporadically, being turned on and off as required; as such, applications with memory leaks would often be terminated before they introduced a noticeable degradation in system performance. In today's “24-7” environment, however, in which applications are rarely turned off, even a “slow leak” in memory will eventually degrade system performance.
If applications are not sufficiently protected from each other with regard to memory allocation, a memory leak in one application will have the effect of slowing down and eventually crashing other applications as well. This ‘side-effect’ of an application's memory leak often makes it difficult to determine which application is responsible for the degradation in system performance, particularly in environments that do not allow for applications to be purposely shut down to perform proper fault isolation tasks.
Conventional memory utilization analyzers take ‘snapshots’ of an application's use of memory over time, then compare snapshots to identify growth patterns. For example, in “Memory Analysis Best Practices Within Eclipse”, a white paper by Steven Haines, published by QUEST SOFTWARE™, June 2008, the author instructs: “[t]ake a snapshot of the heap before your code runs[; t]ake a snapshot of the heap after your code runs[; and . . . t]he best strategy is to compute the difference between the “before” heap and the “after” heap, and then verify that new objects are expected to be in the heap. If they're not, then you have identified a memory leak and can resolve it!” (“Memory Analysis Best Practices Within Eclipse”, page 7, lines 3-15; the heap is a list of all objects to which memory is currently allocated.) A variety of analysis tools are available for presenting a visualization of the contents of the heap, including a ‘dominator tree’ representation that illustrates the hierarchical dependencies among the objects in the heap, detailed further below.
The author of the aforementioned white paper identifies the shortcomings of the conventional ‘snapshot’ approach to memory utilization analysis: “However, keep in mind that only you, as the developer of the code, can properly understand these ‘lingering objects’ in the context of your application and determine whether there is truly a memory leak” (“Memory Analysis Best Practices Within Eclipse”, page 7, lines 27-29). That is, merely comparing a list of before-and-after active objects does not, per se, identify a memory leak. Additionally, if the code segment being analyzed is lengthy, with numerous functions and subroutines, it is generally very difficult to identify where the memory leaks are being created, without searching through the code for each instance that each suspect object is likely to have been instantiated in memory.
It would be advantageous to be able to monitor the memory utilization of an application over time, to clearly identify memory leaks or other anomalies. It would also be advantageous to be able to perform this monitoring of memory utilization in a production environment without significantly interfering with the operation of the application. It would also be advantageous to be able to identify the cause of memory leaks or other anomalies within the application.
These advantages, and others, can be realized by augmenting an application to record memory allocations and releases as they occur over time, and providing an analysis system that presents characteristic memory utilization patterns to a user for review and analysis. A variety of sampling techniques are used to minimize the impact of this memory utilization monitoring on the performance of the application, and the analysis system is configured to estimate the overall memory utilization based on these samples. Because these samples of the memory allocations are taken continuously as the application is running, the analysis system can provide visualizations of the memory utilization patterns that allow a user to easily recognize anomalous behavior. The analysis system includes an interactive interface that allows the user to trace the cause of the presented memory utilization patterns, and provides statistics regarding memory allocation and release to guide the user in this analysis. In a preferred embodiment, the monitoring of memory utilization also includes conventional heap dumps, and the interactive interface is configured to couple the memory utilization patterns with the conventional presentation of such heap dumps, to facilitate efficient resolution of memory leaks and other anomalies.
Throughout the drawings, the same reference numerals indicate similar or corresponding features or functions. The drawings are included for illustrative purposes and are not intended to limit the scope of the invention.